{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7.1 卷积层"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7.1.1 全连接层的问题\n",
    "\n",
    "我们前几章中介绍的各种神经网络其实都在使用一种连接结构，就是“全连接层”。它的特点是每个单元之间连接所有的前一层单元。这种连接方式使得全连接层能够学习到输入数据之间的非线性关系，并能够在神经网络中扮演重要的角色。但是，全连接层也存在一些主要问题，这些问题主要表现在以下几个方面：\n",
    "\n",
    "1. 参数数量巨大：全连接层中的参数数量随着输入和输出单元数量的增加而急剧增加。这会导致训练时间增加，并且很容易导致过拟合。这么说你可能没有感觉，咱们举个例子你就明白了。假设我们有一个全连接层，该层具有 1000 个输入单元和 100 个输出单元。这意味着该层中有 $1000 \\times 100=100000$ 个权重参数和 100 个偏置参数。这对于较小的神经网络来说可能不是问题，但是对于规模较大的神经网络来说，参数数量的增加可能会导致训练时间增加，并且很容易导致过拟合。例如，如果我们在该层之后再添加一个具有 100 个输入单元和 10 个输出单元的全连接层，则该层中将有 100*10=1000 个权重参数和 10 个偏置参数。这样，我们的神经网络中就有 101000 个参数。如果我们再添加几层全连接层，参数数量将会进一步增加。可以看出，当神经网络中包含许多全连接层时，参数数量可能会变得非常庞大，这对于训练和推理来说都是挑战。\n",
    "\n",
    "2. 对空间不友好：全连接层对输入数据的空间属性没有任何假设，这意味着它不能很好地处理空间相关的数据。例如，图像数据中的像素是有空间位置关系的，而全连接层无法很好地利用这种关系。\n",
    "\n",
    "3. 对小型数据集不友好：由于全连接层中的参数数量非常庞大，因此在训练数据较少的情况下，很容易导致过拟合。\n",
    "\n",
    "4. 对计算资源不友好：全连接层中的大量参数意味着它需要大量的计算资源进行训练和推理。这对于计算资源有限的系统来说是一个挑战，尤其是在模型规模较大的情况下。\n",
    "\n",
    "5. 对于序列数据不友好：全连接层无法很好地处理序列数据，因为它无法保留序列中各个元素之间的顺序信息。例如，在处理文本数据时，单词的顺序是非常重要的，但全连接层无法保留这种顺序信息。\n",
    "\n",
    "鉴于这些问题，在许多应用中，人们选择使用其他类型的神经网络层，例如卷积层和循环层，来解决这些问题。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7.1.2 多层感知机的局限\n",
    "\n",
    "前面学习的多层感知机，也就是仅仅使用全连接层的深度神经网络，除了上述问题外，在处理实际应用的时候还有很多局限。例如，人工智能试图解决的一大类问题都涉及到图像处理。而多层感知机在这方面遇到了两个显著的困难：平移不变性和局部性问题。\n",
    "\n",
    "#### 1. 平移不变性 （Translation Invariance）\n",
    "它指的是模型对输入数据的平移不敏感。例如，考虑一张 $n$ 维的输入数据 $\\mathbf{x}$ 和一个平移矩阵 $\\mathbf{T}$，其中 $\\mathbf{T}$ 是一个 $n\\times n$ 的矩阵。对于一个平移不变的模型 $f$，对于任意的 $\\mathbf{x}$ 和 $\\mathbf{T}$，都有 $f(\\mathbf{x})=f(\\mathbf{T}\\mathbf{x})$。这意味着，如果我们将输入数据 $\\mathbf{x}$ 平移一小段距离，则模型应该能够正确地识别输入中的对象。举个例子来说，在图像分类任务中，如果我们将一张图像平移一小段距离，则模型应该能够正确地识别图像中的对象。\n",
    "\n",
    "<img src=\"../images/7-1-1.png\" width=\"50%\"></img>\n",
    "\n",
    "但是，多层感知机很难学习到这种平移不变性，因为它们是由许多全连接层组成的，其中每层的权重参数都是固定的。因此，多层感知机很难对输入数据的平移进行建模。\n",
    "\n",
    "#### 2. 局部性\n",
    "\n",
    "局部性是指模型对输入数据的局部信息敏感。这是神经网络中非常好的一个特性，因为在许多应用中，输入数据通常包含大量局部信息，而这些局部信息往往可以帮助我们识别数据中的模式。比如图像分类任务中，可以借助图像局部信息识别对象。然而遗憾的是，多层感知机很难学习到这种局部性。为什么呢？因为它们是由许多全连接层组成的，其中每层的权重参数都是固定的。这意味着，多层感知机无法从输入数据的局部信息中学习到有用的特征。还是以图像分类任务来说，假设我们有一张图像，其中包含一个狗的头部，这是想要识别的目标对象。如果我们使用的是多层感知机来进行图像分类，那么需要将整张图像输入到模型中，并期望模型能够从图像的整体信息中识别出狗的头部。然而，由于多层感知机没有学习到局部性的能力，因此很难做到这一点。\n",
    "\n",
    "正是上述问题，促使科学家们思考如何改进多层感知机这样都是全连接层的网络。由此发展出来了卷积神经网络等一系列更加强大的高级模型。想要学好卷积神经网络，先要从什么是卷积开始。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### 7.1.3 卷积\n",
    "\n",
    "卷积其实是一种数学运算，常用于信号处理和图像处理领域。它的基本思想是将一个函数与另一个函数进行点积，并通过滑动窗口的方式计算整个输入数据的值。一维卷积的数学表示如下：\n",
    "\n",
    "$$(f*g)(t)=\\int_{-\\infty}^{\\infty}f(\\tau)g(t-\\tau)d\\tau$$\n",
    "\n",
    "其中 $f$ 和 $g$ 分别表示输入函数和卷积核函数，$*$ 表示卷积运算符，$t$ 表示时间，$\\tau$ 表示滑动窗口的位置。\n",
    "\n",
    "二维卷积的数学公式类似，如下所示：\n",
    "\n",
    "$$(f*g)(x,y)=\\int_{-\\infty}^{\\infty}\\int_{-\\infty}^{\\infty}f(x',y')g(x-x',y-y')dx'dy'$$\n",
    "\n",
    "其中 $f$ 和 $g$ 分别表示输入函数和卷积核函数，$*$ 表示卷积运算符，$x$ 和 $y$ 表示二维平面上的位置，$x'$ 和 $y'$ 表示滑动窗口的位置。\n",
    "\n",
    "**梗直哥提示：卷积的概念普通人理解起来还是有些抽象，不太好懂。推荐看下我在B站和知乎做的关于卷积的视频，深入浅出，几分钟让你过目不忘。**\n",
    "\n",
    "说完了卷积公式，你一定还是有点蒙，它在图像处理当中怎么使用呢？我们来看看。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7.1.4 图像卷积\n",
    "\n",
    "在图像处理中，卷积通常用于图像卷积和图像滤波。图像卷积是指将图像与卷积核进行卷积运算，从而得到新的图像。图像滤波是指使用卷积核对图像进行滤波操作，从而得到滤波后的图像。\n",
    "\n",
    "例如，假设我们有一幅二维图像 $\\mathbf{X}\\in\\mathbb{R}^{H\\times W}$，其中 $H$ 和 $W$ 分别表示图像的高度和宽度。我们希望使用卷积核 $\\mathbf{W}\\in\\mathbb{R}^{k_h\\times k_w}$ 对图像进行滤波操作。那么，我们可以使用以下公式对图像进行卷积：\n",
    "\n",
    "$$\\mathbf{Y}[i, j]=\\sum_{m=1}^{k_h}\\sum_{n=1}^{k_w}\\mathbf{X}[i+m-1, j+n-1]\\mathbf{W}[m, n]$$\n",
    "\n",
    "其中 $\\mathbf{Y}[i, j]$ 表示输出图像的第 $i$ 行第 $j$ 列的元素值，$\\mathbf{X}[i+m-1, j+n-1]$ 表示输入图像的第 $i+m-1$ 行第 $j+n-1$ 列的元素值，$\\mathbf{W}[m, n]$ 表示卷积核的第 $m$ 行第 $n$ 列的元素值。\n",
    "\n",
    "我们常说图像卷积能捕捉图像局部特征，这到底是为什么呢？在后续小节中梗直哥将会给你详细地进一步介绍。简单来说，这是因为卷积核可以在输入图像上滑动，并在每一个位置对图像进行卷积运算。在卷积运算的过程中，卷积核可以与输入图像的局部信息进行交互，并捕捉到这些局部信息。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7.1.5 卷积层\n",
    "\n",
    "神经网络卷积层是一种特殊的神经网络层，它使用了图像卷积的思想来处理输入数据。卷积层通常用于处理图像数据，但它也可以用于处理一些其他的数据，例如文本数据。\n",
    "\n",
    "卷积层的主要作用是提取输入数据的局部特征，并将这些局部特征抽象为更高级的特征。卷积层通常由若干个卷积核组成，每个卷积核都是一个小的二维矩阵，可以在输入数据上滑动，并对输入数据进行卷积运算。卷积层的输出是一个多维数组，每个元素的值都是卷积核与输入数据的局部信息进行交互得到的结果。\n",
    "卷积层有许多参数，包括卷积核的大小、填充大小、步幅大小以及输出通道数。这些参数可以调整卷积层的表现。例如，卷积核的大小决定了局部信息的大小，填充大小决定了输出图像的大小，步幅大小决定了卷积核在输入图像上的滑动步幅，输出通道数决定了卷积层输出的多少信息。卷积层通常与池化层配合使用，以便对输入数据进行下采样。池化层可以使用最大池化或平均池化来进行下采样，这样可以减少卷积层的参数数量，同时还可以增强卷积层的平移不变性。卷积层是深度学习模型中常用的层之一，它在计算机视觉、语音识别、自然语言处理等领域都得到了广泛应用。\n",
    "\n",
    "前面我们提到，卷积层和全连接层相比大幅减少了参数量，这是为什么呢？原因主要有两个：首先，卷积层使用了共享权值的方式，使得卷积层中的参数数量比全连接层少得多。共享权值的方式意味着，同一个卷积层内的所有节点都使用相同的权值。这与全连接层不同，全连接层中的每个节点都有一个独立的权值。因此卷积层的参数数量要比全连接层少得多。其次，卷积层的输入是一个多维数组，而全连接层的输入是一个向量。因此，卷积层的输入数据中有更多的元素，而这些元素之间存在较强的相关性，可以帮助卷积层进一步减少参数数量。举个例子，假设我们有一个三维输入图像 $\\mathbf{X}\\in\\mathbb{R}^{H\\times W\\times C}$，其中 $H$ 和 $W$ 分别表示输入图像的高度和宽度，$C$ 表示通道数。假设我们使用一个全连接层来处理这个图像，那么全连接层的输入数据 $\\mathbf{x}\\in\\mathbb{R}^{HWC}$ 就是一个向量，全连接层包含的参数数量就是 $\\mathcal{O}(HWC)$ 级别的。如果使用卷积层来处理这个图像，我们可以使用若干个卷积核来提取图像的局部特征。假设我们使用 $K$ 个卷积核，每个卷积核的大小是 $k_h\\times k_w$，那么卷积层包含的参数数量就是 $\\mathcal{O}(k_hk_wKC)$ 级别的。可以看出，卷积层的参数数量要比全连接层的参数数量少得多。此外，卷积层还有一些参数可以调节，例如填充大小、步幅大小等，这些参数也可以帮助卷积层减少参数数量。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**梗直哥提示：本节咱们一下子介绍了不少新名词，尤其是讲卷积层的过程中。如果你上来理解不了，记不住别着急，后续小节会给大家逐步讲清楚。同时，这些更加详细的知识点的掌握，有赖于你在实战中总结经验，慢慢就熟悉了。当然，如果你想大幅节省时间，解答自己在学习中的各种困惑，欢迎选修《梗直哥深度学习：python实战》。**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Next 7-2 图像卷积](./7-2%20图像卷积.ipynb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
